﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using TodoCore;

namespace XmlTodoWrapper
{
    public class XmlTasklist
    {
        private static readonly List<Task> Tasks = new List<Task>();
        public List<Task> Read(string fileName)
        {
            try
            {
                var xmlTodoList = new XmlDocument();

                xmlTodoList.Load(fileName);

                if (xmlTodoList.GetElementsByTagName("TODOLIST").Count > 0)
                {
                    XmlNode xndList = xmlTodoList.GetElementsByTagName("TODOLIST").Item(0);


                    if (xndList != null)
                    {
                        if (xndList.HasChildNodes)
                        {
                            for (int i = 0; i < xndList.ChildNodes.Count; i++)
                            {
                                AppendNewTask(null, xndList.ChildNodes.Item(i));
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                throw new Exception("Get tasksFrom XML Failed");
            }
            return Tasks;
        }

        public void Write(string fileName, List<Task> tasks)
        {
            throw new NotImplementedException();
        }


        private void AppendNewTask(Task parentTask, XmlNode xmlNodeTask)
        {
            Task newTask;
            if (xmlNodeTask.Name.ToUpper() == "TASK")
            {
                newTask = readFromXml(xmlNodeTask);

                if (parentTask != null)
                {
                    newTask.ParentTaskId = parentTask.TaskId;
                }
                if (xmlNodeTask.HasChildNodes)
                {
                    for (int i = 0; i < xmlNodeTask.ChildNodes.Count; i++)
                    {
                        AppendNewTask(newTask, xmlNodeTask.ChildNodes.Item(i));
                    }
                }
                AddTask(newTask);
            }
            else if (xmlNodeTask.Name.ToUpper() == "COMMENTS")
            {
                if (parentTask != null)
                {
                    parentTask.CommentsStr = xmlNodeTask.InnerText;
                }
            }
        }

        private static void AddTask(Task newTask)
        {
            if (Tasks.Where(t => t.TaskId == newTask.TaskId).Count() == 1)
            {
                Task existingTask = Tasks.Single(t => t.TaskId == newTask.TaskId);
                if (newTask.LastMod > existingTask.LastMod)
                {
                    Tasks[Tasks.IndexOf(existingTask)] = newTask;
                }
            }
            else
            {
                Tasks.Add(newTask);
            }
        }


        /// <summary>
        /// Reads in this tasks properties from the xml node
        /// </summary>
        /// <param name="xndTask"></param>
        public Task readFromXml(XmlNode xndTask)
        {
            Task NewTask = new Task();
            try
            {
                if (xndTask.Attributes.GetNamedItem("ALLOCATEDBY") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("ALLOCATEDBY").InnerText.Length > 0)
                    {
                        NewTask.AllocatedBy = xndTask.Attributes.GetNamedItem("ALLOCATEDBY").InnerText;
                    }
                }
                if (xndTask.Attributes.GetNamedItem("CATEGORY") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("CATEGORY").InnerText.Length > 0)
                    {
                        NewTask.Category = xndTask.Attributes.GetNamedItem("CATEGORY").InnerText;
                    }
                }
                if (xndTask.Attributes.GetNamedItem("COLOUR") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("COLOUR").InnerText.Length > 0)
                    {
                        NewTask.Colour = Convert.ToInt64(xndTask.Attributes.GetNamedItem("COLOUR").InnerText);
                    }
                }
                if (xndTask.Attributes.GetNamedItem("COMMENTS") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("COMMENTS").InnerText.Length > 0)
                    {
                        NewTask.CommentsStr = xndTask.Attributes.GetNamedItem("COMMENTS").InnerText;
                    }
                }
                if (xndTask.Attributes.GetNamedItem("COMMENTSTYPE") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("COMMENTSTYPE").InnerText.Length > 0)
                    {
                        NewTask.CommentsType = xndTask.Attributes.GetNamedItem("COMMENTSTYPE").InnerText;
                    }
                }
                if (xndTask.Attributes.GetNamedItem("CREATIONDATE") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("CREATIONDATE").InnerText.Length > 0)
                    {
                        NewTask.CreationDate =
                            DateTime.FromOADate(
                                Convert.ToDouble(xndTask.Attributes.GetNamedItem("CREATIONDATE").InnerText));
                    }
                }
                if (xndTask.Attributes.GetNamedItem("CUSTOMCOMMENTS") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("CUSTOMCOMMENTS").InnerText.Length > 0)
                    {
                        NewTask.RtfComments = xndTask.Attributes.GetNamedItem("CUSTOMCOMMENTS").InnerText;
                    }
                }
                if (xndTask.Attributes.GetNamedItem("DUEDATE") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("DUEDATE").InnerText.Length > 0)
                    {
                        NewTask.DueDate =
                            DateTime.FromOADate(Convert.ToDouble(xndTask.Attributes.GetNamedItem("DUEDATE").InnerText));
                    }
                }
                if (xndTask.Attributes.GetNamedItem("DONEDATE") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("DONEDATE").InnerText.Length > 0)
                    {
                        NewTask.DoneDate =
                            DateTime.FromOADate(Convert.ToDouble(xndTask.Attributes.GetNamedItem("DONEDATE").InnerText));
                    }
                }
                if (xndTask.Attributes.GetNamedItem("FILEREFPATH") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("FILEREFPATH").InnerText.Length > 0)
                    {
                        NewTask.FileRefPath = xndTask.Attributes.GetNamedItem("FILEREFPATH").InnerText;
                    }
                }
                if (xndTask.Attributes.GetNamedItem("ID") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("ID").InnerText.Length > 0)
                    {
                        NewTask.TaskId = Convert.ToInt16(xndTask.Attributes.GetNamedItem("ID").InnerText);
                    }
                }
                if (xndTask.Attributes.GetNamedItem("LASTMOD") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("LASTMOD").InnerText.Length > 0)
                    {
                        NewTask.LastMod =
                            DateTime.FromOADate(Convert.ToDouble(xndTask.Attributes.GetNamedItem("LASTMOD").InnerText));
                    }
                }

                NewTask.Title = xndTask.Attributes.GetNamedItem("TITLE").InnerText;

                if (xndTask.Attributes.GetNamedItem("PERCENTDONE") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("PERCENTDONE").InnerText.Length > 0)
                    {
                        NewTask.PercentComplete = Convert.ToInt16(xndTask.Attributes.GetNamedItem("PERCENTDONE").InnerText);
                    }
                }
                if (xndTask.Attributes.GetNamedItem("PERSON") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("PERSON").InnerText.Length > 0)
                    {
                        NewTask.AllocatedTo = xndTask.Attributes.GetNamedItem("PERSON").InnerText;
                    }
                }
                if (xndTask.Attributes.GetNamedItem("POS") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("POS").InnerText.Length > 0)
                    {
                        NewTask.Position = Convert.ToInt16(xndTask.Attributes.GetNamedItem("POS").InnerText);
                    }
                }
                if (xndTask.Attributes.GetNamedItem("PRIORITY") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("PRIORITY").InnerText.Length > 0)
                    {
                        NewTask.Priority = Convert.ToInt16(xndTask.Attributes.GetNamedItem("PRIORITY").InnerText);
                    }
                }
                if (xndTask.Attributes.GetNamedItem("PRIORITYCOLOR") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("PRIORITYCOLOR").InnerText.Length > 0)
                    {
                        NewTask.PriorityColour = Convert.ToInt64(xndTask.Attributes.GetNamedItem("PRIORITYCOLOR").InnerText);
                    }
                }
                if (xndTask.Attributes.GetNamedItem("PRIORITYWEBCOLOR") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("PRIORITYWEBCOLOR").InnerText.Length > 0)
                    {
                        NewTask.PriorityWebColour = xndTask.Attributes.GetNamedItem("PRIORITYWEBCOLOR").InnerText;
                    }
                }
                if (xndTask.Attributes.GetNamedItem("RISK") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("RISK").InnerText.Length > 0)
                    {
                        NewTask.Risk = Convert.ToInt16(xndTask.Attributes.GetNamedItem("RISK").InnerText);
                    }
                }
                if (xndTask.Attributes.GetNamedItem("STARTDATE") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("STARTDATE").InnerText.Length > 0)
                    {
                        NewTask.StartDate =
                            DateTime.FromOADate(Convert.ToDouble(xndTask.Attributes.GetNamedItem("STARTDATE").InnerText));
                    }
                }
                if (xndTask.Attributes.GetNamedItem("STATUS") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("STATUS").InnerText.Length > 0)
                    {
                        NewTask.Status = xndTask.Attributes.GetNamedItem("STATUS").InnerText;
                    }
                }
                if (xndTask.Attributes.GetNamedItem("TEXTCOLOUR") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("TEXTCOLOUR").InnerText.Length > 0)
                    {
                        NewTask.TextColour = xndTask.Attributes.GetNamedItem("TEXTCOLOUR").InnerText;
                    }
                }
                if (xndTask.Attributes.GetNamedItem("TEXTWEBCOLOUR") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("TEXTWEBCOLOUR").InnerText.Length > 0)
                    {
                        NewTask.TextWebColour = xndTask.Attributes.GetNamedItem("TEXTWEBCOLOUR").InnerText;
                    }
                }
                if (xndTask.Attributes.GetNamedItem("TIMEESTIMATE") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("TIMEESTIMATE").InnerText.Length > 0)
                    {
                        NewTask.HoursEst = Convert.ToSingle(xndTask.Attributes.GetNamedItem("TIMEESTIMATE").InnerText);
                    }
                }
                if (xndTask.Attributes.GetNamedItem("TIMESPENT") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("TIMESPENT").InnerText.Length > 0)
                    {
                        NewTask.TimeSpent = Convert.ToDecimal(xndTask.Attributes.GetNamedItem("TIMESPENT").InnerText);
                    }
                }
                if (xndTask.Attributes.GetNamedItem("VERSION") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("VERSION").InnerText.Length > 0)
                    {
                        NewTask.VersionStr = xndTask.Attributes.GetNamedItem("VERSION").InnerText;
                    }
                }
                if (xndTask.Attributes.GetNamedItem("WEBCOLOUR") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("WEBCOLOUR").InnerText.Length > 0)
                    {
                        NewTask.WebColour = xndTask.Attributes.GetNamedItem("WEBCOLOUR").InnerText;
                    }
                }
                if (xndTask.Attributes.GetNamedItem("OUTLOOKAPPOINTMENTID") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("OUTLOOKAPPOINTMENTID").InnerText.Length > 0)
                    {
                        NewTask.OutlookAppointmentID = xndTask.Attributes.GetNamedItem("OUTLOOKAPPOINTMENTID").InnerText;
                    }
                }
                if (xndTask.Attributes.GetNamedItem("OUTLOOKAPPOINTMENTENABLED") != null)
                {
                    if (xndTask.Attributes.GetNamedItem("OUTLOOKAPPOINTMENTENABLED").InnerText.Length > 0)
                    {
                        NewTask.OutlookAppointmentEnabled =
                            Convert.ToBoolean(xndTask.Attributes.GetNamedItem("OUTLOOKAPPOINTMENTENABLED").InnerText);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception reading todolist [" + e.Message + "]");
            }

            if (NewTask.PercentComplete == 100)
            {
                NewTask.Complete = true;
            }
            return NewTask;
        }
    }
}
